﻿using System;
using System.Net;
using System.Net.Sockets;
using System.Collections.Generic;
using System.Text;
using System.Runtime;
using System.Runtime.Serialization;
using System.Net.NetworkInformation;

namespace PickGold.Util.Net
{
	static class common
	{
	}

	/// <summary>
	/// 
	/// </summary>
	public static class NetUtil
	{
		/// <summary>
		/// 
		/// </summary>
		/// <param name="socket"></param>
		/// <returns></returns>
		public static UdpClient NoBlocking(UdpClient socket)
		{
			var IOC_IN = 0x80000000U;
			var IOC_VENDOR = 0x18000000U;
			var SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12U;
			socket.Client.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null);
			return socket;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="socket"></param>
		/// <returns></returns>
		public static Socket NoBlocking(Socket socket)
		{
			var IOC_IN = 0x80000000U;
			var IOC_VENDOR = 0x18000000U;
			var SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12U;
			socket.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null);
			return socket;
		}

		/// <summary>
		/// 取本地计算机的IP地址
		/// </summary>
		/// <param name="option">等于零取地址；大于零取掩码；小于零取广播；</param>
		/// <returns></returns>
		public static IPAddress[] GetIPV4Addresses(int option)
		{
			var ls = new List<int>();
			foreach (var ni in NetworkInterface.GetAllNetworkInterfaces())
			{
				foreach (var ip in ni.GetIPProperties().UnicastAddresses)
				{
					var p = ip.Address;
					if (IPAddress.IsLoopback(p))
						continue;

					var bs = p.GetAddressBytes();
					if (bs == null || bs.Length != 4)
						continue;

					if (option == 0)
					{
						var i = BitConverter.ToInt32(bs, 0);
						if (!ls.Contains(i))
							ls.Add(i);
						continue;
					}

					var ms = ip.IPv4Mask.GetAddressBytes();
					if (ms == null)
						continue;

					if (option > 0)
					{
						var i = BitConverter.ToInt32(ms, 0);
						if (!ls.Contains(i))
							ls.Add(i);
						continue;
					}

					var v = BitConverter.ToInt32(ms, 0) ^ -1;
					v = v | BitConverter.ToInt32(bs, 0);
					if (!ls.Contains(v))
						ls.Add(v);
				}
			}
			var vs = new IPAddress[ls.Count];
			for (var i = ls.Count - 1; i >= 0; i--)
				vs[i] = new IPAddress(BitConverter.GetBytes(ls[i]));
			return vs;
		}

		/// <summary>
		/// 从本地计算机配置地址掩码的广播地址
		/// </summary>
		/// <param name="address">地址</param>
		/// <returns></returns>
		public static IPAddress GetIPV4Broadcast(IPAddress address)
		{
			if (address == null)
				return null;

			if (address == IPAddress.Any ||
				address == IPAddress.Loopback ||
				address == IPAddress.None ||
				address == IPAddress.IPv6Any ||
				address == IPAddress.IPv6Loopback ||
				address == IPAddress.IPv6None ||
				address == IPAddress.Broadcast)
				return IPAddress.Broadcast;

			if (IPAddress.IsLoopback(address))
				return IPAddress.Broadcast;

			var bs = address.GetAddressBytes();
			if (bs == null || bs.Length != 4)
				return null;

			foreach (var ni in NetworkInterface.GetAllNetworkInterfaces())
			{
				foreach (var ip in ni.GetIPProperties().UnicastAddresses)
				{
					var p = ip.Address;
					if (p != address)
						continue;

					var ms = ip.IPv4Mask.GetAddressBytes();
					if (ms == null)
						continue;

					var v = BitConverter.ToInt32(ms, 0) ^ -1;
					v = v | BitConverter.ToInt32(bs, 0);
					address = new IPAddress(BitConverter.GetBytes(v));
					return address;
				}
			}
			return null;
		}
	}
}
